#include "DList.h"

DLN* BuyListNode(DListDataType x) {
	DLN* newnode = (DLN*)malloc(sizeof(DLN));
	newnode->next = NULL;
	newnode->prev = NULL;
	newnode->data = x;

	return newnode;
}

DLN* ListInit() {
	DLN* phead = BuyListNode(0);
	phead->next = phead;
	phead->prev = phead;

	return phead;
}

void ListDestory(DLN* phead) {
	DLN* tail = phead->prev;
	DLN* prev = tail->prev;
	while (prev != phead) {
		free(tail);
		tail = prev;
		prev = prev->prev;
	}
	free(phead);
	phead = NULL;
}

void ListPrint(DLN* phead) {
	assert(phead);
	DLN* locate = phead;
	while (locate->next != phead) {
		printf("%d ", locate->data);
		locate = locate->next;
	}
	printf("\n");
}

void ListPushBack(DLN* phead, DListDataType x) {
	assert(phead);
	DLN* tail = phead;
	while (tail->next != phead) {
		tail = tail->next;
	}
	DLN* newnode = BuyListNode(x);
	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = phead;
	phead->prev = newnode;
}

void ListPushFront(DLN* phead, DListDataType x) {
	assert(phead);
	DLN* newnode = BuyListNode(x);
	DLN* tmp = phead->next;
	newnode->next = tmp;
	tmp->prev = newnode;
	phead->next = newnode;
	newnode->prev = phead;
}

void ListPopFront(DLN* phead) {
	assert(phead);
	assert(phead->next != phead);

	DLN* obj = phead->next;
	DLN* next = obj->next;
	next->prev = phead;
	phead->next = next;
	free(obj);
	obj = NULL;
}

void ListPopBack(DLN* phead) {
	assert(phead);
	assert(phead->next != phead);

	DLN* tail = phead->prev;
	DLN* prev = tail->prev;
	prev->next = phead;
	phead->prev = prev;
	free(tail);
	tail = NULL;
}

DLN* ListFind(DLN* phead, DListDataType x) {
	assert(phead);
	DLN* tail = phead->next;
	while (tail != phead) {
		if (tail->data == x)
			return tail;

		tail = tail->next;
	}
	return NULL;
}

void ListInsert(DLN* pos, DListDataType x) {
	assert(pos);
	DLN* prev = pos->prev;
	DLN* newnode = BuyListNode(x);

	newnode->next = pos;
	newnode->prev = prev;
	prev->next = newnode;
	pos->prev = newnode;
}

void ListErase(DLN* pos) {
	assert(pos);
	DLN* prev = pos->prev;
	DLN* next = pos->next;
	next->prev = prev;
	prev->next = next;
	free(pos);
	pos = NULL;
}